
package com.adc.quicktools.timeformat;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TimeMaskUtil{
	
	private static SimpleDateFormat sm=new SimpleDateFormat("yyyy-MM-dd");
	
	private static Calendar c=Calendar.getInstance();
	
	
	public static void main(String args[]){
		TimeMaskUtil pro=new TimeMaskUtil();
		
		System.out.println(pro.calculate("[yyyy][MM][dd]", "2012-10-16"));
//		System.out.println(pro.calculate("[yyyy][MM]0[p]", "2011-11-30"));
//		System.out.println(pro.calculate("sdsdsds[yyyy]-[MM+1]ffffffffff", "2011-12-5"));
//		System.out.println(pro.calculate("sdsdsds[yyyy]-[MM+2]ffffffffff", "2011-12-5"));
//		System.out.println(pro.calculate("sdsdsds[yyyy]-[MM+3]ffffffffff", "2011-12-5"));
//		System.out.println(pro.calculate("sdsdsds[yyyy]-[MM]-[x+1]ffffffffff", "2011-12-5"));
//		System.out.println(pro.calculate("sdsdsds[yyyy]-[MM]-[x+2]ffffffffff", "2011-12-5"));
//		System.out.println(pro.calculate("sdsdsds[yyyy]-[MM]-[x+3]ffffffffff", "2011-12-5"));
//		System.out.println(pro.calculate("sdsdsds[yyyy]-[MM]-[x+4]ffffffffff", "2011-12-5"));
//		System.out.println(pro.calculate("sdsdsds[yyyy]-[MM]-[x+5]ffffffffff", "2011-12-5"));
//		System.out.println(pro.calculate("sdsdsds[yyyy]-[MM]-[x+6]ffffffffff", "2011-12-5"));
//		System.out.println(pro.calculate("sdsdsds[yyyy]-[MM]-[x+7]ffffffffff", "2011-12-5"));
//		System.out.println(pro.calculate("sdsdsds[yyyy]-[MM]-[x+8]ffffffffff", "2011-12-5"));
//		System.out.println(pro.calculate("sdsdsds[yyyy]-[MM]-[p-1]ffffffffff", "2011-12-5"));
//		System.out.println(pro.calculate("sdsdsds[yyyy]-[MM]-[p-2]ffffffffff", "2011-12-5"));
//		System.out.println(pro.calculate("sdsdsds[yyyy]-[MM]-[p-3]ffffffffff", "2011-12-5"));
//		System.out.println(pro.calculate("sdsdsds[yyyy]-[MM]-[p-4]ffffffffff", "2011-12-5"));
//		System.out.println(pro.calculate("sdsdsds[yyyy]-[MM]-[dd-1]ffffffffff", "2011-12-5"));
//		System.out.println(pro.calculate("sdsdsds[yyyy]-[MM]-[dd-2]ffffffffff", "2011-12-5"));
//		System.out.println(pro.calculate("sdsdsds[yyyy]-[MM]-[dd-3]ffffffffff", "2011-12-5"));
//		System.out.println(pro.calculate("sdsdsds[yyyy]-[MM]-[dd-4]ffffffffff", "2011-12-5"));
//		System.out.println(pro.calculate("sdsdsds[yyyy]-[MM]-[dd-5]ffffffffff", "2011-12-5"));
//		System.out.println(pro.calculate("sdsdsds[yyyy]-[MM]-[dd-6]ffffffffff", "2011-12-5"));
//		System.out.println(pro.calculate("sdsdsds[yyyy]-[MM]-[dd-7]ffffffffff", "2011-12-5"));		
//		System.out.println(pro.calculate("sdsdsds[yyyy]-[MM]-[dd-8]ffffffffff", "2011-12-5"));
//		System.out.println(pro.calculate("sdsdsds[yyyy]-[MM]-[dd-9]ffffffffff", "2011-12-5"));
//		System.out.println(pro.calculate("sdsdsds[yyyy]-[MM]-[dd-10]ffffffffff", "2011-12-5"));
//		System.out.println(pro.calculate("sdsdsds[yyyy]-[MM]-[dd-11]ffffffffff", "2011-12-5"));
//		
//		String dayRegex = "\\[dd[^0-9]([0-9]+)?\\]" ;
//		String dayRegex1 = "[^d\\-0-9]|dd" ;
		
//		String dayRegex = "\\[dd([+-][0-9]+)?\\]" ;
//		String dayRegex1 = "\\[|\\]|\\+|dd" ;
//		
//		String minDay=pro.getValue(dayRegex,dayRegex1,"[dd+101]");
//		System.out.println(minDay);
	}
	
	
	/**
	 * 
	 *  {yyyy}-{M}-{d}   
		{yyyy}-{h}
		{yyyy}-{j}
		{yyyy}-{x}
		{yyyy}-{M}
		{yyyy}

	 * rule :规则串 ， time：时间，dateFormat：时间尺度

	 * @param rule  :规则串
	 * @param time  计算的起始时间 
	 * @param dateFormat ：时间尺度 时间类型
	 * @return
	 */
	public static String calculate(String rule,String time) {
		//计算结果
		String date=queryDate(rule,time);
		
		String result="";
	    if(rule.contains("[x"))
	    {
//			//替换旬
	    	result=replaceDay(rule,date.substring(9),"\\[x([+-][0-9]+)?\\]");
	    }
	    else if(rule.contains("[p"))
	    {
	    	//替换侯
			result=replaceDay(rule,date.substring(9),"\\[p([+-][0-9]+)?\\]");
	    }
	    else 
	    {	 //替换日期
			 result=replaceDay(rule,date.substring(8),"\\[dd([+-][0-9]+)?\\]");
	    }
		//替换日期
		 result=replaceDay(result,date.substring(8),"\\[dd([+-][0-9]+)?\\]");
		 //替换月
		 result=replaceDay(result,date.substring(5,7),"\\[MM([+-][0-9]+)?\\]");
		 
		 //替换年
		 result=replaceDay(result,date.substring(0,4),"\\[yyyy([+-][0-9]+)?\\]");
		 
		 //替换短年
		 result=replaceDay(result,date.substring(2,4),"\\[yy([+-][0-9]+)?\\]");
		
		return result;
	}
	
	/**
	 * 
	 * @param rule  规则
	 * @param replaceWith  替换符
	 * @param reg   正则表达式
	 * @return  替换后的字符串
	 */
	private static String replaceDay(String rule,String replaceWith,String reg){
		String result=rule;
		
		Pattern pattern = Pattern.compile(reg) ;
		Matcher matcher = pattern.matcher(rule) ;
		if(matcher.find()){
			String yearVal = matcher.group() ;
			result = matcher.replaceFirst(replaceWith) ;
		}
	
	    return result;	
	}
	
	private static String queryDate(String rule,String time){
		String yearRegex = "\\[yyyy([+-][0-9]+)?\\]" ;
		String yearRegex1 = "\\[|\\]|\\+|yyyy" ;
		
		String monRegex = "\\[MM([+-][0-9]+)?\\]" ;
		String monRegex1 = "\\[|\\]|\\+|MM" ;
		
		String dayRegex = "\\[dd([+-][0-9]+)?\\]" ;
		String dayRegex1 = "\\[|\\]|\\+|dd" ;
		
		String houRegex = "\\[p([+-][0-9]+)?\\]" ;
		String houRegex1 = "\\[|\\]|\\+|p" ;
		
		String xunRegex = "\\[x([+-][0-9]+)?\\]" ;
		String xunRegex1 = "\\[|\\]|\\+|x" ;
		Date date;
		try {
			String minXun=getValue(xunRegex,xunRegex1,rule);
			String minHou=getValue(houRegex,houRegex1,rule);
			String minDay=getValue(dayRegex,dayRegex1,rule);
			String minMon=getValue(monRegex,monRegex1,rule);
			String minYear=getValue(yearRegex,yearRegex1,rule);
			
			date = sm.parse(time);
			c.setTime(date);
			
			if(minXun!=null&&!minXun.trim().equals("")){

				//先计算侯再加和
				int day = c.get(Calendar.DAY_OF_MONTH);
				//将day转化为hou，如果是31号，特殊处理为6侯
				int xun = (31==day) ? 3 : ((day+9)/10);
				//指定日期转化为侯数后按计算规则计算
				xun+=Integer.parseInt(minXun);
				if(Integer.parseInt(minXun)>0){
					//达到7侯则月进一位
					c.add(Calendar.MONTH, (xun-1)/3);
					//进位后的余数是当前的侯数，因为不存在0侯，所以当侯数整除6的时候取值为6侯
					c.set(Calendar.DAY_OF_MONTH, xun%3==0?3:xun%3);
					
				}else{
					if(xun<=0)
					{
						//当侯为负值的时候，月要退一位，以便给侯进位
						c.add(Calendar.MONTH, xun/3-1);
						//当后为负数的时候，侯从月借来6侯
						c.set(Calendar.DAY_OF_MONTH, -xun%3==0?3:3+xun%3);
					}else
					{
						//当候减去负数后不为负数时
						c.set(Calendar.DAY_OF_MONTH, xun);
					}
				}
			}else if(rule.contains("[x"))
			{
				int day = c.get(Calendar.DAY_OF_MONTH);
				//将day转化为hou，如果是31号，特殊处理为6侯
				int hou = (31==day) ? 3 : ((day+9)/10);
				c.set(Calendar.DAY_OF_MONTH, hou);
			}
			
			if(minHou!=null&&!minHou.trim().equals("")){
				//先计算天数，加和，再计算侯
//				c.add(Calendar.DAY_OF_MONTH, Integer.parseInt(minHou)*5);
//				int day = c.get(Calendar.DAY_OF_MONTH);
//				int hou = (31==day) ? 6 : ((day+4)/5);
//				c.set(Calendar.DAY_OF_MONTH, hou);
				//先计算侯再加和
				int day = c.get(Calendar.DAY_OF_MONTH);
				//将day转化为hou，如果是31号，特殊处理为6侯
				int hou = (31==day) ? 6 : ((day+4)/5);
				//指定日期转化为侯数后按计算规则计算
				hou+=Integer.parseInt(minHou);
				if(Integer.parseInt(minHou)>0){
					//达到7侯则月进一位
					c.add(Calendar.MONTH, (hou-1)/6);
					//进位后的余数是当前的侯数，因为不存在0侯，所以当侯数整除6的时候取值为6侯
					c.set(Calendar.DAY_OF_MONTH, hou%6==0?6:hou%6);
					
				}else{
					if(hou<=0)
					{
						//当侯为负值的时候，月要退一位，以便给侯进位
						c.add(Calendar.MONTH, hou/6-1);
						//当后为负数的时候，侯从月借来6侯
						c.set(Calendar.DAY_OF_MONTH, -hou%6==0?6:6+hou%6);
					}else
					{
						//当候减去负数后不为负数时
						c.set(Calendar.DAY_OF_MONTH, hou);
					}
				}
			}else if(rule.contains("[p"))
			{
				int day = c.get(Calendar.DAY_OF_MONTH);
				//将day转化为hou，如果是31号，特殊处理为6侯
				int hou = (31==day) ? 6 : ((day+4)/5);
				c.set(Calendar.DAY_OF_MONTH, hou);
			}
			if(minDay!=null&&!minDay.trim().equals("")){
				c.add(Calendar.DAY_OF_MONTH, Integer.parseInt(minDay));
			}
			if(minMon!=null&&!minMon.trim().equals("")){
				c.add(Calendar.MONTH, Integer.parseInt(minMon));
			}
			if(minYear!=null&&!minYear.trim().equals("")){
				c.add(Calendar.YEAR, Integer.parseInt(minYear));
			}
			return sm.format(c.getTime());
			
			
		} catch (ParseException e) {
			e.printStackTrace();
		}catch(Exception e){
			e.printStackTrace();
		}
		return null;
	}
	
	public static String getValue(String regex,String regex1,String rule)
	{
//		String dayRegex = "\\[dd(-[0-9]+)?\\]" ;
//		String dayRegex1 = "\\[|\\]|\\-|dd" ;
		String result = "" ;
		Pattern pattern = Pattern.compile(regex) ;
		Matcher matcher = pattern.matcher(rule) ;
		if(matcher.find()){
			String yearVal = matcher.group() ;
			//String regex1 = "\\{|\\}|\\-|yyyy" ;
			pattern = Pattern.compile(regex1) ;
			Matcher matcher1 = pattern.matcher(yearVal) ;
			if(matcher1.find()){
				result = matcher1.replaceAll("") ;
			}
		}
		return result ;
	}

}
